/**
 *
 * 用户路由件
 *
 * all/get/post/delete/put 是路由件目前所完全支持的方法
 * 匹配表达式直接作为方法对象的key，触发方法直接作为方法对象的value
 * 我们把每个表达式对应的方法称作为触发方法，这个方法只有两个传入参数
 * ctx 基于原koa2上扩展的功能对象，支持原koa2所有ctx方法
 * next 返回它能够跳过触发函数进入下一个匹配表达式的触发函数
 * ctx {
 * 	hd	处理件对象，通过它去调用对应处理件内方法
 * 	common 工具类
 * 	config 配置数据
 * 	fs 文件操作模块
 * 	uploader 上传文件处理模块
 * 	mysql 数据库连接池，通过它去调用对应连接的操作方法
 * 	redis Redis数据库连接池，通过它去调用对应连接的操作方法
 * 	cron 定时任务池，通过它操作对应定时任务
 * }
 * 
 * 注意事项：
 * 触发方法应该加上async关键字，否则框架可能无法正确同步的返回数据
 * 调用处理件方法时，如果处理件方法使用了async关键字请务必保证加上await关键字等到此方法完成返回
 *
 */

module.exports = {
	get: {

		'/test': async ctx => {
			// await ctx.hd.sys.encryptTableData('course', [
			// 		'courseName'
			// 	], 'id')
			//await ctx.hd.sys.test()
			return 1
		},

		//获取学生数据
		'/user/student': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			return await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuName', 'stuSex', 'stuPhoto', 'classGrade', 'className')
		},

		//获取学生抢课数据
		'/user/student/grabCourse': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {stuId, stuPwd, stuGrade, majorId} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd', 'stuClass', 'stuGrade', 'majorId')
			let grabCourses =  await ctx.hd.sys.getGrabCourseByMajorId(majorId)
			if(grabCourses.length == 0) {
				// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
				// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
				await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
				grabCourses = await ctx.hd.zf.getGrabCourse(ctx.user)
				await ctx.hd.sys.updateGrabCourses(0, grabCourses, majorId, stuGrade)
			}
			return grabCourses
		},

		//获取学生一卡通数据
		'/user/student/card': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			let {cardPwd = '888888'} = ctx.bodyData
			let stuCardData = await ctx.hd.card.getStuCardCache(userId)
			if(stuCardData)
				return stuCardData
			const {stuId} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId')
			const data = await ctx.hd.card.getCardDataByUserId(userId, 'cardPwd')
			if(data && data.cardPwd)
				cardPwd = data.cardPwd
			await ctx.hd.card.cardLogin(0, stuId, cardPwd, ctx.user)
			stuCardData = await ctx.hd.card.getStuCardDataFromOrigin(ctx.user)
			ctx.hd.card.updateStuCardDataByUserId(userId, cardPwd, stuCardData)
			return stuCardData
		},

		//查询课程表
		'/user/student/syllabus': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {courseYear, courseTerm, courseTime, courseStartDate, courseEndDate} = await ctx.hd.sys.getCommonData('courseYear', 'courseTerm', 'courseTime', 'courseStartDate', 'courseEndDate')
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			console.log('学生密码', stuPwd)
			let stuSyllabus = await ctx.hd.syllabus.getStuSyllabusCache(stuId, courseYear, courseTerm)
			if(!stuSyllabus)
				stuSyllabus = await ctx.hd.syllabus.getStuSyllabusData(stuId, courseYear, courseTerm)
			if(!stuSyllabus) {
				// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
				// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
				await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
				const {courseData} = await ctx.hd.syllabus.getStuSyllabusDataFromOrigin(courseYear, courseTerm, ctx.user)
				await ctx.hd.syllabus.addStuCourseData(stuId, courseData, {courseYear, courseTerm})
				stuSyllabus = courseData
			}
			//应用全校调课数据
			await ctx.hd.syllabus.applyCourseChange(stuSyllabus)
			return {
				stuCourseTime: {
					courseYear,
					courseTerm,
					courseTime,
					courseStartDate,
					courseEndDate
				},
				stuSyllabus
			}
		},

		//查询成绩
		'/user/student/score': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			let {courseYear, courseTerm, scoreOpen, certScoreOpen} = await ctx.hd.sys.getCommonData('courseYear', 'courseTerm', 'scoreOpen', 'certScoreOpen')
			scoreOpen = ctx.common.checkSwitch(scoreOpen)
			certScoreOpen = ctx.common.checkSwitch(certScoreOpen)
			const stuScoreData = await ctx.hd.score.getStuScoreCache(userId)
			console.log('结果', stuScoreData)
			if(stuScoreData)
				return Object.assign(stuScoreData, {courseYear, courseTerm, scoreOpen, certScoreOpen})
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd', 'stuScoreId')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			let stuCredit = 0,scoreList = {}, certScoreList = {}
			if(scoreOpen)
				({stuCredit, stuGPA, scoreList} = await ctx.hd.score.getStuScore(ctx.user))
			if(certScoreOpen)
				certScoreList = await ctx.hd.score.getStuCertScore(ctx.user)
			await ctx.hd.score.updateStuScoreData(userId, stuCredit, stuGPA, scoreList, certScoreList)
			return {
				stuCredit,
				stuGPA,
				courseYear,
				courseTerm,
				scoreList,
				certScoreList,
				scoreOpen,
				certScoreOpen
			}
		},

		//查询借阅记录
		'/user/student/library/loan': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			let loanList = await ctx.hd.library.getLoanCache(userId)
			if(loanList)
				return loanList
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			await ctx.hd.library.libraryLogin(stuId, stuPwd.substring(stuPwd.length - 6, stuPwd.length), ctx.user)
			loanList = await ctx.hd.library.getLoan(ctx.user)
			return loanList
		},

		//查看图书详情
		'/user/student/library/book/:bookId': async ctx => {
			await ctx.auth.allow('all')
			const { bookId } = ctx.params
			let bookInfo = await ctx.hd.library.getBookCache(bookId)
			if(bookInfo)
				return bookInfo
			const bookData = await ctx.hd.library.getBookData(bookId, ctx.user)
			return bookData
		},

		//获取关联列表
		'/user/student/syllabus/correl': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {stuId} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId')
			return await ctx.hd.syllabus.getCorrelSyllabusData(stuId)
		},

		//查询关联学生的课程表
		'/user/student/:otherStuId/correl/syllabus': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {otherStuId} = ctx.params
			const {stuId} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId')
			if(!await ctx.hd.syllabus.checkCorrelSyllabus(stuId, otherStuId))
				return ctx.error('-2060', 'syllabus correl relation not found')
			const {courseYear, courseTerm, courseTime, courseStartDate, courseEndDate} = await ctx.hd.sys.getCommonData('courseYear', 'courseTerm', 'courseTime', 'courseStartDate', 'courseEndDate')
			let stuSyllabus = await ctx.hd.syllabus.getStuSyllabusCache(otherStuId, courseYear, courseTerm)
			if(!stuSyllabus)
				stuSyllabus = await ctx.hd.syllabus.getStuSyllabusData(otherStuId, courseYear, courseTerm)
			if(!stuSyllabus)
				return ctx.error('-2063', 'correl syllabus not found')
			return {
				stuCourseTime: {
					courseYear,
					courseTerm,
					courseTime,
					courseStartDate,
					courseEndDate
				},
				stuSyllabus
			}
		},

		//获取评价课程列表
		'/user/student/evaluation/list': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			let evaluationData = await ctx.hd.evaluation.getStuEvaluationCache(userId)
			if(evaluationData)
				return evaluationData
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			evaluationData = await ctx.hd.evaluation.getStuEvaluationData(ctx.user)
			return evaluationData
		},

		//获取单个课程评教数据
		'/user/student/evaluation/:evaluationId': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {evaluationId} = ctx.params
			let evaluationData = await ctx.hd.evaluation.getStuSingleEvaluationCahce(userId, evaluationId)
			if(evaluationData)
				return evaluationData
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			evaluationData = await ctx.hd.evaluation.getStuEvaluationDataById(evaluationId, ctx.user)
			return evaluationData
		}

	},
	post: {

		//绑定学生用户
		'/user/student': async ctx => {
			await ctx.auth.allow('normal')
			const {stuId, stuPwd} = ctx.bodyData
			if(await ctx.hd.student.checkStuBind(stuId))
				return ctx.error('-2003', 'student bind id only one time')
			//const stuHashPwd = ctx.hd.student.encryptStuPwd(stuId, stuPwd)
			//await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user, stuHashPwd)
			//await ctx.hd.zf.updateCasPwd(stuHashPwd, ctx.user)
			//await ctx.hd.zf.activeCasZfSession(0, '', ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			let stuInfo = await ctx.hd.zf.getUserInfo(ctx.user)
			const {courseYear, courseTerm} = await ctx.hd.sys.getCommonData('courseYear', 'courseTerm')
			const {courseData} = await ctx.hd.syllabus.getStuSyllabusDataFromOrigin(courseYear, courseTerm, ctx.user)
			console.log(courseData)
			stuInfo.stuSyllabus = courseData
			stuInfo.courseTime = {courseYear, courseTerm}
			return await ctx.hd.student.bindStuUser(stuId, stuPwd, stuInfo, ctx.user)
		},

		//关联Ta课程表
		'/user/student/syllabus/correl': async ctx => {
			await ctx.auth.allow('student')
			const { correlStuId } = ctx.bodyData
			if(await ctx.hd.student.checkStuBind(correlStuId))
				return ctx.error('-2110', 'student is not bind')
			return await ctx.hd.syllabus.bindCorrelSyllabus(correlStuId, ctx.user)
		},

		//匹配关联学生课程表
		'/user/student/syllabus/correl/match': async ctx => {
			await ctx.auth.allow('student')
			const {correlIdList} = ctx.bodyData
		},

		//提交评教
		'/user/student/evaluation': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {evaluationId} = ctx.bodyData
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			return await ctx.hd.evaluation.submitEvaluationTch(evaluationId, ctx.user)
		}

	},
	put: {

		//修改绑定的密码
		'/user/student/password': async ctx => {
			//const {userId} = await ctx.auth.allow('student')
			//const {stuPwd, vCode} = ctx.bodyData
			//const {stuId} = ctx.hd.student.getStuDataByUserId(userId, 'stuId')
			//await ctx.hd.zf.login(0, stuId, stuPwd, vCode, ctx.user)
			//await ctx.hd.user.modifyStuPwd(stuId, stuPwd)
			return 1
		},

		//同步最新课表
		'/user/student/syllabus': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {courseYear, courseTerm, courseTime, courseStartDate, courseEndDate} = await ctx.hd.sys.getCommonData('courseYear', 'courseTerm', 'courseTime', 'courseStartDate', 'courseEndDate')
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			const {courseData} = await ctx.hd.syllabus.getStuSyllabusDataFromOrigin(courseYear, courseTerm, ctx.user)
			await ctx.hd.syllabus.addStuCourseData(stuId, courseData, {courseYear, courseTerm})
			return {
				stuCourseTime: {
					courseYear,
					courseTerm,
					courseTime,
					courseStartDate,
					courseEndDate
				},
				stuSyllabus: courseData
			}
		},

		//同步最新成绩
		'/user/student/score': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			let {courseYear, courseTerm, scoreOpen, certScoreOpen} = await ctx.hd.sys.getCommonData('courseYear', 'courseTerm', 'scoreOpen', 'certScoreOpen')
			scoreOpen = ctx.common.checkSwitch(scoreOpen)
			certScoreOpen = ctx.common.checkSwitch(certScoreOpen)
			//如果在3分钟内其他请求已经完成同步则下次同步直接将该结果返回
			const stuScoreData = await ctx.hd.score.getStuScoreCache(userId)
			if(ctx.common.timestamp() - stuScoreData.syncTime < 180)
				return Object.assign(stuScoreData, {courseYear, courseTerm, scoreOpen, certScoreOpen})
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			let stuCredit = 0,scoreList = {}, certScoreList = {}
			if(scoreOpen)
				({stuCredit, stuGPA, scoreList} = await ctx.hd.score.getStuScore(ctx.user))
			if(certScoreOpen)
				certScoreList = await ctx.hd.score.getStuCertScore(ctx.user)
			await ctx.hd.score.updateStuScoreData(userId, stuCredit, stuGPA, scoreList, certScoreList)
			return {
				stuCredit,
				stuGPA,
				courseYear,
				courseTerm,
				scoreList,
				certScoreList,
				scoreOpen,
				certScoreOpen
			}
		},

		//同步最新学生一卡通数据
		'/user/student/card': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			let {cardPwd = '888888'} = ctx.bodyData
			const {stuId} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId')
			const data = await ctx.hd.card.getCardDataByUserId(userId, 'cardPwd')
			if(data && data.cardPwd)
				cardPwd = data.cardPwd
			await ctx.hd.card.cardLogin(0, stuId, cardPwd, ctx.user)
			stuCardData = await ctx.hd.card.getStuCardDataFromOrigin(ctx.user)
			ctx.hd.card.updateStuCardDataByUserId(userId, cardPwd, stuCardData)
			return stuCardData
		},

		//接受关联课表申请
		'/user/student/syllabus/correl/:msgId/:status': async ctx => {
			await ctx.auth.allow('student')
			const {msgId, status} = ctx.params			
			if(status == 'resolve')
				return await ctx.hd.syllabus.resolveCorrelSyllabus(msgId, ctx.user)
			else if(status == 'reject') {
				return await ctx.hd.syllabus.rejectCorrelSyllabus(msgId, ctx.user)
			}
			else
				return ctx.error('-2053', 'update message status string invalid')
		},

		//同步最新关联学生的课程表
		'/user/student/:otherStuId/correl/syllabus': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {otherStuId} = ctx.params
			const {stuId} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId')
			if(!await ctx.hd.syllabus.checkCorrelSyllabus(stuId, otherStuId))
				return ctx.error('-2060', 'syllabus correl relation not found')
			const {courseYear, courseTerm, courseTime, courseStartDate, courseEndDate} = await ctx.hd.sys.getCommonData('courseYear', 'courseTerm', 'courseTime', 'courseStartDate', 'courseEndDate')
			const {stuPwd:otherStuPwd} = await ctx.hd.student.getStuDataByStuId(otherStuId, 'stuPwd')
			let user = { userId, data: {} }
			// await ctx.hd.zf.casLogin(otherStuId, otherStuPwd, user)
			// await ctx.hd.zf.activeCasZfSession(0, otherStuZfAuthId, user)
			await ctx.hd.zf.zfLogin(0, otherStuId, otherStuPwd, user)
			const {courseData} = await ctx.hd.syllabus.getStuSyllabusDataFromOrigin(courseYear, courseTerm, user)
			await ctx.hd.syllabus.addStuCourseData(otherStuId, courseData, {courseYear, courseTerm})
			return {
				stuCourseTime: {
					courseYear,
					courseTerm,
					courseTime,
					courseStartDate,
					courseEndDate
				},
				stuSyllabus: courseData
			}
		},

		//更新评价课程列表
		'/user/student/evaluation/list': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			evaluationData = await ctx.hd.evaluation.getStuEvaluationData(ctx.user)
			return evaluationData
		},

		//评价教师
		'/user/student/evaluation/:evaluationId': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {evaluationId} = ctx.params
			const {evaluationList, evaluationRemark} = ctx.bodyData
			const {stuId, stuPwd} = await ctx.hd.student.getStuDataByUserId(userId, 'stuId', 'stuPwd')
			// await ctx.hd.zf.casLogin(stuId, stuPwd, ctx.user)
			// await ctx.hd.zf.activeCasZfSession(0, stuZfAuthId, ctx.user)
			await ctx.hd.zf.zfLogin(0, stuId, stuPwd, ctx.user)
			return await ctx.hd.evaluation.evaluationTch(evaluationId, evaluationList, evaluationRemark, ctx.user)
		},

		//设置学生停课状态
		'/user/student/:stuId/suspend/:status':  async ctx => {
			await ctx.auth.allow('teacher', 'inside')
			const {stuId, status} = ctx.params
			if(!ctx.hd.student.checkStuId(stuId))
				return ctx.error('-2010', 'student id invalid')
			if(isNaN(status) || (status != 0 && status != 1))
				return ctx.error('-2084', 'student suspend status value invalid')
			await ctx.hd.student.updateStuSuspendStatus(stuId, Boolean(parseInt(status)))
			return 1
		}

	},
	delete: {

		//解绑学生用户
		'/user/student': async ctx => {
			await ctx.auth.allow('student')
			await ctx.hd.student.untieStuUser(ctx.user)
			return 1
		},

		//解除关联课表
		'/user/student/syllabus/correl/:correlId': async ctx => {
			const {userId} = await ctx.auth.allow('student')
			const {correlId} = ctx.params
			return await ctx.hd.syllabus.untieCorrelSyllabus(correlId)
		}

	}
}